﻿using AutoMapper;
using ServerSide.EFCoreContext;
using ServerSide.Model;
using ServerSide.Model.Dto.MenuDto;
using ServerSide.Model.Dto.RoleDto;
using ServerSide.Model.Other;
using ServerSide.Service.Interface;
using ServerSide.utils;
using System.Data;

namespace ServerSide.Service
{
    public class MenuService : IMenuService
    {
        private readonly MyDBContext _myDBContext;
        private readonly IMapper _mapper;   
        public MenuService(MyDBContext myDBContext,IMapper mapper)
        {
            _myDBContext = myDBContext;
            _mapper = mapper;
        }


        /// <summary>
        /// 查询菜单数据
        /// </summary>
        /// <param name="menuRequest"></param>
        /// <returns></returns>
        public List<Menu> GetMenus(MenuRequest menuRequest)
        {
            List<Menu> allMenus = _myDBContext.Menu.ToList();

            IQueryable<Menu> query = _myDBContext.Menu;

            if (!string.IsNullOrEmpty(menuRequest.MenuName))
            {
                query = query.Where(item => item.Label.Contains(menuRequest.MenuName));
            }
            if (!string.IsNullOrEmpty(menuRequest.Enable))
            {
                query = query.Where(item => item.Enable == int.Parse(menuRequest.Enable));
            }
            List<Menu> menus = query.Where(item => item.ParentId == 0).OrderBy(m => m.MenuSort).ToList();

            GetAllChildren(allMenus, menus);

            return menus;
        }
        /// <summary>
        /// 获取全部子菜单数据
        /// </summary>
        /// <param name="allMenus"></param>
        /// <param name="parentMenus"></param>
        private static void GetAllChildren(List<Menu> allMenus, List<Menu> parentMenus)
        {
            if (parentMenus != null && parentMenus.Any())
            {
                parentMenus.ForEach(parentMenu =>
                {
                    var children = allMenus.Where(m => m.ParentId == parentMenu.Id)
                                           .OrderBy(m => m.MenuSort)
                                           .ToList();
                    if (children != null && children.Any())
                    {
                        parentMenu.Children = children;
                        GetAllChildren(allMenus, children);
                    }
                });
            }
        }
        /// <summary>
        /// 角色页面分配菜单权限是获取所有菜单数据
        /// </summary>
        /// <returns></returns>
        public List<Menu> SelectMenuList()
        {
            List<Menu> allMenus = _myDBContext.Menu.Where(item=>item.Enable==1).ToList();
            List<Menu> menus = _myDBContext.Menu.Where(item => item.ParentId == 0&&item.Enable==1).OrderBy(m => m.MenuSort).ToList();
            GetAllChildren(allMenus, menus);
            return menus;
        }
        public bool AddMenu(MenuAdd menuAdd)
        {
            bool menuExist = _myDBContext.Menu.Where(item => item.Name == menuAdd.Name).Any();
            if (!menuExist)
            {
                Menu menu = _mapper.Map<Menu>(menuAdd);
                menu.CreateTime = GenerateTime.GetCurrentTime();
                _myDBContext.Menu.Add(menu);
                int execSuccess = _myDBContext.SaveChanges();
                if (execSuccess > 0)
                {
                    return true;
                }
            }
            return false;
        }

        public bool BatchDelMenus(List<int> ids)
        {
            try
            {
                List<Menu> menus = _myDBContext.Menu.Where(item => ids.Contains(item.Id)).ToList();

                _myDBContext.Menu.RemoveRange(menus);
                int v = _myDBContext.SaveChanges();
                if (v > 0)
                {
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;

            }
        }

        public bool DelMenu(Menu menu)
        {
            bool exist = _myDBContext.Menu.Any(item => item.Id == menu.Id);
            if (exist)
            {
                _myDBContext.Menu.Remove(menu);
                int execSuccess = _myDBContext.SaveChanges();
                if (execSuccess > 0)
                {
                    return true;
                }
            }
            return false;
        }



        public bool UpdateMenu(Menu menu)
        {
            Menu? menuData = _myDBContext.Menu.Where(item => menu.Id == item.Id).FirstOrDefault();
            if (menuData != null)
            {
                menuData.Name = menu.Name;
                menuData.Label = menu.Label;
                menuData.Path = menu.Path;
                menuData.Icon=menu.Icon;
                menuData.ParentId = menu.ParentId;
                menuData.MenuType = menu.MenuType;
                menuData.MenuSort = menu.MenuSort;
                menuData.KeepAlive = menu.KeepAlive;
                menuData.Perms = menu.Perms;
                menuData.Url = menu.Url;
                menuData.Enable = menu.Enable;
                try
                {
                    _myDBContext.Menu.Update(menuData);
                    int rowsAffected = _myDBContext.SaveChanges();

                    if (rowsAffected > 0)
                    {
                        return true;
                    }
                }
                catch (Exception ex)
                {
                    // 处理异常
                    Console.WriteLine($"An error occurred: {ex.Message}");
                }
            }
            return false;
        }

        public bool UpdateMenuKeepAlive(int id, int keepAlive)
        {
            Menu? menu = _myDBContext.Menu.Where(item => item.Id == id).FirstOrDefault();
            if (menu != null)
            {
                if (keepAlive == 1 || keepAlive == 0)
                {
                    menu.KeepAlive = keepAlive;
                }
                _myDBContext.Menu.Update(menu);
                int v = _myDBContext.SaveChanges();
                if (v > 0)
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 登录时根据用户角色获取相应菜单
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public List<Menu> GetMenuById(int userId)
        {
            //存放父级菜单数据
            List<Menu> menuRes = new List<Menu>();
            List<Menu> currlist = new List<Menu>();

            // 查询当前角色所拥有的菜单
            var user = _myDBContext.User.FirstOrDefault(u => u.Id == userId);
            var roleIds = _myDBContext.UserRole.Where(ur => ur.UserId == userId).Select(ur => ur.RoleId).ToList();
            List<string?> roleNames = roleIds.SelectMany(id => _myDBContext.Role.Where(item => item.Id == id).Select(r=>r.Name)).ToList();
            if (roleNames.Any(rname=>rname!="超级管理员"))
            {
                //当前角色所拥有的的菜单内容
                currlist = _myDBContext.Menu.Join(_myDBContext.RoleMenu,
                    menu => menu.Id,
                    menuRole => menuRole.MenuId,
                    (menu, menuRole) => new { Menu = menu, MenuRole = menuRole })
                    .Where(x => roleIds.Contains(x.MenuRole.RoleId)&&x.Menu.Enable==1)
                    .Select(x => x.Menu)
                    .ToList();
            }
            else
            {
                currlist = _myDBContext.Menu.ToList();
            }

            //获取所有菜单内容
            var allMenus = _myDBContext.Menu.Where(m => m.Enable == 1).ToList();

            if (currlist != null && currlist.Any())
            {
                currlist.ForEach(item =>
                {
                    GetParent(allMenus, item, menuRes);
                });

                List<Menu> menuResList = _mapper.Map<List<Menu>>(currlist.Concat(menuRes).Distinct().ToList());
                return GetTreeData(menuResList);
            }

            return new List<Menu>();
        }


        /// <summary>
        /// 自底向上递归获取当前菜单的父级菜单
        /// </summary>
        /// <param name="allMenus"></param>
        /// <param name="currMenu"></param>
        /// <param name="menuRes"></param>
        private static void GetParent(List<Menu> allMenus, Menu currMenu, List<Menu> menuRes)
        {
            if (currMenu.ParentId == 0)
            {
                menuRes.Add(currMenu);
            }
            else
            {
                var parentMenu = allMenus.FirstOrDefault(m => m.Id == currMenu.ParentId);
                if (parentMenu != null)
                {
                    menuRes.Add(parentMenu);
                    GetParent(allMenus, parentMenu, menuRes);
                }
            }

        }
        /// <summary>
        /// 转成树形菜单列表返回
        /// </summary>
        /// <param name="menuResList"></param>
        /// <returns></returns>
        private static List<Menu> GetTreeData(List<Menu> menuResList)
        {
            List<Menu> MenuRespons = new();
            List<Menu> topLevelMenus = menuResList.Where(m => m.ParentId == 0).OrderBy(item => item.MenuSort).ToList();
            GetChildren(menuResList, topLevelMenus);
            return topLevelMenus;
        }
        /// <summary>
        /// 递归将子菜单添加到父菜单的Children属性（会移除没有权限的页面）
        /// </summary>
        /// <param name="allMenus"></param>
        /// <param name="parentMenus"></param>
        private static void GetChildren(List<Menu> allMenus, List<Menu> parentMenus)
        {
            List<Menu> removeMenus = new List<Menu>();
            if (parentMenus != null && parentMenus.Any())
            {
                parentMenus.ForEach(parentMenu =>
                {
                    var children = allMenus.Where(m => m.ParentId == parentMenu.Id)
                                           .OrderBy(m => m.MenuSort)
                                           .ToList();
                    if (children != null && children.Any())
                    {
                        parentMenu.Children = children;
                        GetChildren(allMenus, children);
                    }else if (parentMenu.MenuType=="M")
                    {
                        removeMenus.Add(parentMenu);
                    }
                });
                foreach (var menuToRemove in removeMenus)
                {
                    parentMenus.Remove(menuToRemove);
                }
            }
        }
    }
}
